const Promise = require('bluebird');

module.exports = function ({JDOrders, AgencysSettles, SettlesLogs, UsersFinances, Users, sequelize}) {

    /**
     * 统计 V2
     */
    JDOrders.analyseV2 = function ({agency_id, inviter_agency_id, user_id, inviter_id}) {
        if (agency_id) {
            return Promise.props({
                all_amount: sequelize.query(`select count(*) as count, ifnull(sum(agency_amount), 0) as amount, ifnull(sum(inviter_agency_amount), 0) as inviter_amount from JDOrders where agency_id = :agency_id and commission > 0 and orderStatusName in('等待确认收货','已完成')`, {
                    type: sequelize.QueryTypes.SELECT,
                    replacements: {agency_id: agency_id}
                }).then(function (rows) {
                    return rows[0]
                }),
                pending_settle: sequelize.query(`select count(*) as count, ifnull(sum(agency_amount), 0) as amount, ifnull(sum(inviter_agency_amount), 0) as inviter_amount from JDOrders where agency_id = :agency_id and commission > 0 and payStatus = '已完成' and agency_settle_id is null`, {
                    type: sequelize.QueryTypes.SELECT,
                    replacements: {agency_id: agency_id}
                }).then(function (rows) {
                    return rows[0]
                }),
                pending_account: sequelize.query(`select count(*) as count, ifnull(sum(agency_amount), 0) as amount, ifnull(sum(inviter_agency_amount), 0) as inviter_amount from JDOrders where agency_id = :agency_id and commission > 0 and payStatus = '等待确认收货' and agency_settle_id is null`, {
                    type: sequelize.QueryTypes.SELECT,
                    replacements: {agency_id: agency_id}
                }).then(function (rows) {
                    return rows[0]
                })
            });
        } else if (inviter_agency_id) {
            return Promise.props({
                all_amount: sequelize.query(`select count(*) as count, ifnull(sum(inviter_agency_amount), 0) as amount from JDOrders where inviter_agency_id = :inviter_agency_id and commission > 0 and payStatus in('等待确认收货','已完成')`, {
                    type: sequelize.QueryTypes.SELECT,
                    replacements: {inviter_agency_id: inviter_agency_id}
                }).then(function (rows) {
                    return rows[0]
                }),
                pending_settle: sequelize.query(`select count(*) as count, ifnull(sum(inviter_agency_amount), 0) as amount from JDOrders where inviter_agency_id = :inviter_agency_id and commission > 0 and payStatus = '已完成' and agency_settle_id is null`, {
                    type: sequelize.QueryTypes.SELECT,
                    replacements: {inviter_agency_id: inviter_agency_id}
                }).then(function (rows) {
                    return rows[0]
                }),
                pending_account: sequelize.query(`select count(*) as count, ifnull(sum(inviter_agency_amount), 0) as amount from JDOrders where inviter_agency_id = :inviter_agency_id and commission > 0 and payStatus = '等待确认收货' and agency_settle_id is null`, {
                    type: sequelize.QueryTypes.SELECT,
                    replacements: {inviter_agency_id: inviter_agency_id}
                }).then(function (rows) {
                    return rows[0]
                })
            });
        } else if (user_id) {
            return Promise.props({
                all_amount: sequelize.query(`select count(*) as count, ifnull(sum(pay_amount), 0) as amount from JDOrders where user_id = :user_id and commission > 0 and payStatus in('等待确认收货','已完成')`, {
                    type: sequelize.QueryTypes.SELECT,
                    replacements: {user_id: user_id}
                }).then(function (rows) {
                    return rows[0]
                }),
                pending_settle: sequelize.query(`select count(*) as count, ifnull(sum(pay_amount), 0) as amount from JDOrders where user_id = :user_id and commission > 0 and payStatus = '已完成'`, {
                    type: sequelize.QueryTypes.SELECT,
                    replacements: {user_id: user_id}
                }).then(function (rows) {
                    return rows[0]
                }),
                pending_account: sequelize.query(`select count(*) as count, ifnull(sum(pay_amount), 0) as amount from JDOrders where user_id = :user_id and commission > 0 and payStatus = '等待确认收货'`, {
                    type: sequelize.QueryTypes.SELECT,
                    replacements: {user_id: user_id}
                }).then(function (rows) {
                    return rows[0]
                })
            });
        } else if (inviter_id) {
            return Promise.props({
                all_amount: sequelize.query(`select count(*) as count, ifnull(sum(inviter_pay_amount), 0) as amount from JDOrders where inviter_id = :inviter_id and commission > 0 and payStatus in('等待确认收货','已完成')`, {
                    type: sequelize.QueryTypes.SELECT,
                    replacements: {inviter_id: inviter_id}
                }).then(function (rows) {
                    return rows[0]
                }),
                pending_settle: sequelize.query(`select count(*) as count, ifnull(sum(inviter_pay_amount), 0) as amount from JDOrders where inviter_id = :inviter_id and commission > 0 and payStatus = '已完成'`, {
                    type: sequelize.QueryTypes.SELECT,
                    replacements: {inviter_id: inviter_id}
                }).then(function (rows) {
                    return rows[0]
                }),
                pending_account: sequelize.query(`select count(*) as count, ifnull(sum(inviter_pay_amount), 0) as amount from JDOrders where inviter_id = :inviter_id and commission > 0 and payStatus = '等待确认收货'`, {
                    type: sequelize.QueryTypes.SELECT,
                    replacements: {inviter_id: inviter_id}
                }).then(function (rows) {
                    return rows[0]
                })
            });
        } else {
            return Promise.props({
                all_amount: sequelize.query(`select count(*) as count, ifnull(sum(commission), 0) as amount from JDOrders where commission > 0 and payStatus in('等待确认收货','已完成')`, {
                    type: sequelize.QueryTypes.SELECT
                }).then(function (rows) {
                    return rows[0]
                }),
                pending_settle: sequelize.query(`select count(*) as count, ifnull(sum(commission), 0) as amount from JDOrders where commission > 0 and payStatus = '已完成'`, {
                    type: sequelize.QueryTypes.SELECT
                }).then(function (rows) {
                    return rows[0]
                }),
                pending_account: sequelize.query(`select count(*) as count, ifnull(sum(commission), 0) as amount from JDOrders where commission > 0 and payStatus = '等待确认收货'`, {
                    type: sequelize.QueryTypes.SELECT
                }).then(function (rows) {
                    return rows[0]
                })
            });
        }
    }

    /**
     * 代理冻结
     */
    JDOrders.agencyFrozenV2 = function (user_id) {
        return Promise.props({
            agency: sequelize.query(`select count(*) as count, ifnull(sum(agency_amount), 0) as amount from JDOrders where agency_id = :agency_id and commission > 0 and agency_amount > 0 and payStatus in ('等待确认收货','已完成') and agency_settle_id is null`, {
                type: sequelize.QueryTypes.SELECT,
                replacements: {agency_id: user_id}
            }).then(function (rows) {
                return rows[0]
            }),
            inviter_agency: sequelize.query(`select count(*) as count, ifnull(sum(inviter_agency_amount), 0) as amount from JDOrders where inviter_agency_id = :inviter_agency_id and commission > 0 and inviter_agency_amount > 0 and payStatus in ('等待确认收货','已完成') and agency_settle_id is null`, {
                type: sequelize.QueryTypes.SELECT,
                replacements: {inviter_agency_id: user_id}
            }).then(function (rows) {
                return rows[0]
            })
        });
    }

    /**
     * 金额入账 V2
     */
    JDOrders.amountV2 = function (order_id) {
        return sequelize.transaction(function (t) {
            return JDOrders.findOne({where: {id: order_id}, transaction: t}).then(function (jdOrder) {
                if (!jdOrder || (jdOrder.orderStatusName != '等待确认收货' && jdOrder.orderStatusName != '已完成')) {
                    return {success: false, message: '京东订单不存在或状态不是等待确认收货和已完成'};
                }
                if (jdOrder.pay_amount > 0) {
                    let data = {is_amount: 1};
                    if (jdOrder.orderStatusName == '已完成') {
                        data.is_settle = 1;
                    }
                    return JDOrders.update(data, {
                        where: {
                            id: jdOrder.id,
                            orderStatusName: jdOrder.orderStatusName,
                            is_amount: 0
                        }, transaction: t
                    }).then(function (result) {
                        if (!result[0]) {
                            return {success: false, message: '京东更新订单失败'}
                        }
                        return UsersFinances.create({
                            partner_id: jdOrder.partner_id,
                            user_id: jdOrder.user_id,
                            amount: jdOrder.pay_amount,
                            type: 'In',
                            operation: 'JDReturnAmount',
                            by: 'JDReturnAmount',
                            order_id: jdOrder.id,
                            is_amount: 1,
                            status: 'Successful'
                        }, {transaction: t}).then(function () {
                            let sql = "update Users u set u.last_order = NOW(), u.order_count = u.order_count + 1, u.frozen = u.frozen + :amount where u.id = :user_id";
                            if (jdOrder.payStatus === '订单结算') {
                                sql = "update Users u set u.last_order = NOW(), u.order_count = u.order_count + 1, u.amount = u.amount + :amount where u.id = :user_id";
                            }
                            return sequelize.query(sql, {
                                replacements: {user_id: jdOrder.user_id, amount: jdOrder.pay_amount},
                                transaction: t
                            }).then(function () {
                                if (jdOrder.inviter_id && jdOrder.inviter_pay_amount > 0) {
                                    return UsersFinances.create({
                                        partner_id: jdOrder.partner_id,
                                        user_id: jdOrder.inviter_id,
                                        amount: jdOrder.inviter_pay_amount,
                                        type: 'In',
                                        operation: 'JDInviterAmount',
                                        by: 'JDInviterAmount',
                                        order_id: jdOrder.id,
                                        is_amount: 1,
                                        note: jdOrder.user_id,
                                        status: 'Successful'
                                    }, {transaction: t}).then(function () {
                                        let inviterSql = "update Users u set u.last_order = NOW(), u.frozen = u.frozen + :amount where u.id = :user_id";
                                        if (jdOrder.payStatus === '订单结算') {
                                            inviterSql = "update Users u set u.last_order = NOW(), u.amount = u.amount + :amount where u.id = :user_id";
                                        }
                                        return sequelize.query(inviterSql, {
                                            replacements: {
                                                user_id: jdOrder.inviter_id,
                                                amount: jdOrder.inviter_pay_amount
                                            },
                                            transaction: t
                                        });
                                    }).then(function () {
                                        return {success: true};
                                    });
                                }
                                return {success: true};
                            });
                        });
                    });
                }
                return {success: true};
            });
        }).catch(function (e) {
            if (e) {
                console.error('\n', e.stack || e.message);
            }
            return {success: false, message: e.message || ''};
        });
    }

    /**
     * 欺诈 V2
     */
    JDOrders.shamV2 = function (order) {
        if (!order.id || !order.user_id) {
            return {success: false, message: '参数错误'};
        }
        return sequelize.transaction(function (t) {
            return JDOrders.update({is_sham: 1}, {
                where: {id: order.id, is_sham: 0}, transaction: t
            }).then(function (result) {
                if (!result[0]) {
                    return {success: false, message: '更新订单失败'}
                }
                return sequelize.query("update Users u set u.sham_count = u.sham_count + 1 where u.id = :user_id", {
                    replacements: {user_id: order.user_id},
                    transaction: t
                }).then(function () {
                    return {success: true};
                });
            });
        }).catch(function (e) {
            if (e) {
                console.error('\n', e.stack || e.message);
            }
            return {success: false, message: e.message || ''};
        });
    }

    /**
     * 取消欺诈 V2
     */
    JDOrders.cancelShamV2 = function (order) {
        if (!order.id || !order.user_id) {
            return {success: false, message: '参数错误'};
        }
        return sequelize.transaction(function (t) {
            return JDOrders.update({is_sham: 0}, {
                where: {id: order.id, is_sham: 1}, transaction: t
            }).then(function (result) {
                if (!result[0]) {
                    return {success: false, message: '更新订单失败'}
                }
                return sequelize.query("update Users u set u.sham_count = u.sham_count - 1 where u.id = :user_id", {
                    replacements: {user_id: order.user_id},
                    transaction: t
                }).then(function () {
                    return {success: true};
                });
            });
        }).catch(function (e) {
            if (e) {
                console.error('\n', e.stack || e.message);
            }
            return {success: false, message: e.message || ''};
        });
    }

    /**
     * 订单失效 V2
     */
    JDOrders.backV2 = function (order) {
        if (order.pay_amount > 0) {
            if (order.is_amount === 0) {
                return {success: false, message: '订单状态不能退款'};
            }
            if (order.is_payed || order.is_settle) {
                JDOrders.shamV2(order);
            }
            return sequelize.transaction(function (t) {
                return JDOrders.update({is_back: 1}, {
                    where: {id: order.id, is_amount: 1, is_back: 0},
                    transaction: t
                }).then(function (result) {
                    if (!result[0]) {
                        return {success: false, message: '更新订单失败'}
                    }
                    return UsersFinances.create({
                        partner_id: order.partner_id,
                        user_id: order.user_id,
                        amount: order.pay_amount,
                        type: 'Out',
                        operation: 'JDReturnBack',
                        by: 'JDReturnBack',
                        order_id: order.id,
                        is_amount: 1,
                        status: 'Successful'
                    }, {transaction: t}).then(function () {
                        if (order.is_settle || order.is_payed) {
                            return sequelize.query("update Users u set u.amount = u.amount - :amount where u.id = :user_id", {
                                replacements: {user_id: order.user_id, amount: order.pay_amount},
                                transaction: t
                            });
                        } else {
                            return sequelize.query("update Users u set u.frozen = u.frozen - :amount where u.id = :user_id", {
                                replacements: {user_id: order.user_id, amount: order.pay_amount},
                                transaction: t
                            });
                        }
                    }).then(function () {
                        if (order.inviter_id && order.inviter_pay_amount > 0) {
                            return UsersFinances.create({
                                partner_id: order.partner_id,
                                user_id: order.inviter_id,
                                amount: order.inviter_pay_amount,
                                type: 'Out',
                                operation: 'JDInviterBack',
                                by: 'JDInviterBack',
                                order_id: order.id,
                                is_amount: 1,
                                note: order.user_id,
                                status: 'Successful'
                            }, {transaction: t}).then(function () {
                                if (order.is_settle || order.is_payed) {
                                    return sequelize.query("update Users u set u.amount = u.amount - :amount where u.id = :user_id", {
                                        replacements: {user_id: order.inviter_id, amount: order.inviter_pay_amount},
                                        transaction: t
                                    });
                                } else {
                                    return sequelize.query("update Users u set u.frozen = u.frozen - :amount where u.id = :user_id", {
                                        replacements: {user_id: order.inviter_id, amount: order.inviter_pay_amount},
                                        transaction: t
                                    });
                                }
                            }).then(function () {
                                return {success: true};
                            });
                        }

                        return {success: true};
                    });
                });
            }).catch(function (e) {
                if (e) {
                    console.error('\n', e.stack || e.message);
                }
                return {success: false, message: e.message || ''};
            });
        }
        return {success: true};
    }

    /**
     * 订单已支付 V2
     */
    JDOrders.payedCheck = function (row) {
        if (row.user_id && row.pay_amount > 0 && (row.orderStatusName === '等待确认收货' || row.orderStatusName === '已完成') && row.is_payed === 0) {
            return true;
        }
        return false;
    }

    /**
     * 订单已支付 V2
     */
    JDOrders.payedV2 = function (order) {
        if (order.pay_amount > 0) {
            if (order.is_amount === 0) {
                return {success: false, message: '订单状态不能支付'};
            }
            return sequelize.transaction(function (t) {
                return JDOrders.update({is_payed: 1, is_settle: 1}, {
                    where: {id: order.id, is_amount: 1, is_payed: 0},
                    transaction: t
                }).then(function (result) {
                    if (!result[0]) {
                        return {success: false, message: '更新订单失败'}
                    }
                    return UsersFinances.create({
                        partner_id: order.partner_id,
                        user_id: order.user_id,
                        amount: order.pay_amount,
                        type: 'Out',
                        operation: 'JDReturnPay',
                        by: 'JDReturnPay',
                        order_id: order.id,
                        is_amount: 1,
                        status: 'Successful'
                    }, {transaction: t}).then(function () {
                        if (order.is_settle) {
                            return sequelize.query("update Users u set u.amount = u.amount - :amount where u.id = :user_id", {
                                replacements: {user_id: order.user_id, amount: order.pay_amount},
                                transaction: t
                            }).then(function () {
                                return {success: true};
                            });
                        } else {
                            return sequelize.query("update Users u set u.frozen = u.frozen - :amount where u.id = :user_id", {
                                replacements: {user_id: order.user_id, amount: order.pay_amount},
                                transaction: t
                            }).then(function () {
                                return {success: true};
                            });
                        }
                    });
                });
            }).catch(function (e) {
                if (e) {
                    console.error('\n', e.stack || e.message);
                }
                return {success: false, message: e.message || ''};
            });
        }
        return {success: true};
    }

    /**
     * 订单结算 V2
     */
    JDOrders.settleV2 = function (order) {
        if (order.pay_amount > 0) {
            if (order.is_amount === 0 || order.is_payed === 1) {
                return {success: false, message: '订单状态订单结算'};
            }
            return sequelize.transaction(function (t) {
                return JDOrders.update({is_settle: 1}, {
                    where: {id: order.id, is_amount: 1, is_payed: 0, is_settle: 0},
                    transaction: t
                }).then(function (result) {
                    if (!result[0]) {
                        return {success: false, message: '更新订单失败'}
                    }
                    return sequelize.query("update Users u set u.frozen = u.frozen - :amount, u.amount = u.amount + :amount where u.id = :user_id", {
                        replacements: {user_id: order.user_id, amount: order.pay_amount},
                        transaction: t
                    }).then(function () {
                        if (order.inviter_id && order.inviter_pay_amount > 0) {
                            return sequelize.query("update Users u set u.frozen = u.frozen - :amount, u.amount = u.amount + :amount where u.id = :user_id", {
                                replacements: {user_id: order.inviter_id, amount: order.inviter_pay_amount},
                                transaction: t
                            }).then(function () {
                                return {success: true};
                            });
                        }
                        return {success: true};
                    });
                });
            }).catch(function (e) {
                if (e) {
                    console.error('\n', e.stack || e.message);
                }
                return {success: false, message: e.message || ''};
            });
        }
        return {success: true};
    }

    /**
     * 代理结算 V2
     */
    JDOrders.agencySettleV2 = function (user, auto_amount) {
        return sequelize.transaction(function (t) {
            return Promise.resolve().then(function () {
                if (user && user.inviter_id) {
                    return Users.findOne({
                        where: {id: user.inviter_id, level: ['Agency', 'Partner']},
                        attributes: ['id']
                    });
                }
            }).then(function (inviterAgency) {
                return AgencysSettles.create({
                    type: 'JD',
                    partner_id: user.partner_id,
                    agency_id: user.id,
                    auto_amount: auto_amount || 0
                }, {transaction: t}).then(function (agencysSettle) {
                    return sequelize.query(`update JDOrders set agency_settle_id = :agency_settle_id where agency_id = :agency_id and commission > 0 and orderStatusName = '已完成' and agency_settle_id is null`, {
                        replacements: {agency_id: user.id, agency_settle_id: agencysSettle.id},
                        transaction: t
                    }).then(function () {
                        return JDOrders.findAll({
                            where: {agency_settle_id: agencysSettle.id, orderStatusName: '已完成'},
                            attributes: ['id', 'commission', 'agency_amount', 'inviter_agency_amount'],
                            raw: true,
                            transaction: t
                        }).then(function (jdOrders) {
                            return JDOrders.findAll({
                                where: {
                                    agency_settle_id: {$ne: null},
                                    agency_back_id: null,
                                    agency_id: user.id,
                                    $or: {ynDetail: '取消订单', ynName: '无效'}
                                },
                                attributes: ['id', 'commission', 'agency_amount', 'inviter_agency_amount'],
                                raw: true,
                                transaction: t
                            }).then(function (backOrders) {
                                let total_amount = 0, back_amount = 0,
                                    total_agency_amount = 0, total_inviter_agency_amount = 0,
                                    back_agency_amount = 0, back_inviter_agency_amount = 0,
                                    backOrdersIds = [];
                                for (let i in jdOrders) {
                                    total_amount += parseFloat(jdOrders[i].commission) || 0;
                                    total_agency_amount += parseFloat(jdOrders[i].agency_amount) || 0;
                                    total_inviter_agency_amount += parseFloat(jdOrders[i].inviter_agency_amount) || 0;
                                }
                                if (backOrders && backOrders.length) {
                                    for (let i in backOrders) {
                                        backOrdersIds.push(backOrders[i].id);
                                        back_amount += parseFloat(backOrders[i].commission) || 0;
                                        back_agency_amount += parseFloat(backOrders[i].agency_amount) || 0;
                                        back_inviter_agency_amount += parseFloat(backOrders[i].inviter_agency_amount) || 0;
                                    }
                                }
                                if (total_amount === 0 && back_amount === 0) {
                                    throw new Error('可结算和可退款金额都为0');
                                }
                                let settle_amount = (total_amount - back_amount).toFixed(2);
                                let agency_amount = (total_agency_amount - back_agency_amount).toFixed(2);
                                let inviter_agency_amount = (total_inviter_agency_amount - back_inviter_agency_amount).toFixed(2);
                                let data = {
                                    total_amount: total_amount,
                                    back_amount: back_amount,
                                    settle_amount: settle_amount,
                                    agency_scale: user.agency_scale,
                                    agency_amount: agency_amount,
                                    ext_data: JSON.stringify({
                                        jdOrders: jdOrders,
                                        backOrders: backOrders
                                    })
                                }
                                if (inviterAgency) {
                                    data.inviter_agency_id = inviterAgency.id;
                                    data.inviter_agency_scale = user.inviter_agency_scale;
                                    data.inviter_agency_amount = inviter_agency_amount;
                                }
                                return AgencysSettles.update(data, {
                                    where: {id: agencysSettle.id},
                                    transaction: t
                                }).then(function () {
                                    if (backOrdersIds.length) {
                                        return JDOrders.update({agency_back_id: agencysSettle.id}, {
                                            where: {id: backOrdersIds},
                                            transaction: t
                                        });
                                    }
                                }).then(function () {
                                    return {
                                        success: true,
                                        data: {
                                            id: agencysSettle.id,
                                            settle_amount: data.settle_amount,
                                            agency_amount: data.agency_amount,
                                            inviter_agency_amount: data.inviter_agency_amount
                                        }
                                    };
                                });
                            });
                        });
                    });
                });
            });
        }).catch(function (e) {
            if (e) {
                console.error('\n', e.stack || e.message);
            }
            return {success: false, message: e.message || ''};
        });
    }

    /**
     * 批量代理结算 V2
     */
    JDOrders.agencyBatchSettleV2 = function (partner, auto_amount) {
        let where = partner ? {level: ['Partner', 'Agency'], partner_id: partner.id} : {
            level: ['Partner', 'Agency'],
            agency_auto_settle: 1
        };
        return Users.findAll({where: where, raw: true}).then(function (users) {
            let ids = [];
            return Promise.mapSeries(users, function (user) {
                ids.push(user.id);
                return JDOrders.agencySettleV2(user, auto_amount);
            }).then(function (results) {
                let successful = 0, failed = 0;
                for (let i in results) {
                    if (results[i].success) {
                        successful += 1;
                    } else {
                        failed += 1;
                    }
                }
                SettlesLogs.create({
                    opt: 'JDBatchSettle',
                    ext_data: JSON.stringify({
                        ids: ids,
                        successful: successful,
                        failed: failed
                    }),
                    user_id: partner ? partner.id : null
                });
                return {success: true, successful: successful, failed: failed};
            });
        });
    };
}